package com.xneure.utils.cipher;

/**
 * 凯撒算法
 */
public class Caesar{
	public static final Caesar CAESAR = new Caesar();
	private String table;
	private int seedA = 1103512045;
	private int seedB = 8658542;

	public Caesar(String table,int seed){
		this.table = chaos(table,seed,table.length());
	}

	public Caesar(String table){
		this(table,11);
	}

	public Caesar(){
		this(11);
	}

	public Caesar(int seed){
		this("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ",seed);
	}

	public char dict(int i,boolean reverse){
		int s = table.length(), index = reverse ? s - i : i;
		return table.charAt(index);
	}

	public int dict(char c,boolean reverse){
		int s = table.length(), index = table.indexOf(c);
		if(index > -1){
			return reverse ? s - index : index;
		}else{
			return index;
		}
	}

	public int seed(int seed){
		return (int)((seed * seedA + seedB) & 0x7fffffffL);
	}

	public String chaos(String data,int seed,int cnt){
		StringBuilder buf = new StringBuilder(data);
		char tmp;
		int a, b, r = data.length();
		for(int i = 0;i < cnt;i += 1){
			seed = seed(seed);
			a = seed % r;
			seed = seed(seed);
			b = seed % r;
			tmp = buf.charAt(a);
			buf.setCharAt(a,buf.charAt(b));
			buf.setCharAt(b,tmp);
		}
		return buf.toString();
	}

	public String crypto(boolean reverse,int key,String text){
		StringBuilder buf = new StringBuilder();
		int m, s = table.length(), e = text.length();
		for(int i = 0;i < e;i += 1){
			m = dict(text.charAt(i),reverse);
			if(m < 0){
				buf.append(String.valueOf(text.charAt(i)));
			}else{
				m = m + key + i;
				buf.append(dict(m % s,reverse));
			}
		}
		return buf.toString();
	}

	public String encode(int key,String text){
		return crypto(false,key,text);
	}

	public String decode(int key,String text){
		return crypto(true,key,text);
	}

}
